package com.bwie.sms.config;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.transaction.RabbitTransactionManager;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.annotation.PostConstruct;

@Configuration
public class RabbitMQConfig implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnsCallback{

    public static final String QUEUE = "msgQueue";
    public static final String EXCHANGE = "msgExchange";
    public static final String ROUTINGKEY = "msgKey";



    public static final Logger logger = LoggerFactory.getLogger(RabbitMQConfig.class);


    @Autowired
    private RabbitTemplate rabbitTemplate;


    //创建消息转换器
    @Bean
    public MessageConverter messageConverter(){
        return new Jackson2JsonMessageConverter();
    }



    @Bean
    public Queue queue(){
        return new Queue(QUEUE,true);
    }

    @Bean
    public DirectExchange directExchange(){

        return new DirectExchange(EXCHANGE);

    }

    @Bean
    public Binding binding(){
        return BindingBuilder.bind(queue()).to(directExchange()).with(ROUTINGKEY);
    }



//    @Primary
//    @Bean
//    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory){
//        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
//        rabbitTemplate.setMessageConverter(messageConverter());
//
//        this.rabbitTemplate = rabbitTemplate;
//        rabbitTemplate();
//        return rabbitTemplate;
//    }

    /**
     * 开启事务机制  针对生产者投递消息到交换机或队列  注意:事务机制和消息确认机制不能同时使用
     * @param connectionFactory
     * @return
     */
    @Bean
    public RabbitTransactionManager transactionManager(ConnectionFactory connectionFactory){
        return new RabbitTransactionManager(connectionFactory);
    }


    @PostConstruct
    public void rabbitTemplate(){

        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnsCallback(this);
    }




    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String s) {

        if (ack){
            logger.info("{}消息到达交换机",correlationData.getId());
        }else {
            logger.info("{}消息丢失", correlationData.getId());
        }

    }

    @Override
    public void returnedMessage(ReturnedMessage returnedMessage) {

        logger.error("{}消息未到达队列",returnedMessage.getMessage().getMessageProperties().getMessageId());

    }
}
